package org.fisco.bcos.asset.contract;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Event;
import org.fisco.bcos.sdk.abi.datatypes.Function;
import org.fisco.bcos.sdk.abi.datatypes.Type;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.generated.Int256;
import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple3;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.contract.Contract;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.eventsub.EventCallback;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

@SuppressWarnings("unchecked")
public class Asset extends Contract {
  public static final String[] BINARY_ARRAY = {
    "608060405234801561001057600080fd5b5061002861002d640100000000026401000000009004565b610185565b600061100190508073ffffffffffffffffffffffffffffffffffffffff166356004b6a6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845260078152602001807f745f617373657400000000000000000000000000000000000000000000000000815250602001848103835260078152602001807f6163636f756e74000000000000000000000000000000000000000000000000008152506020018481038252600b8152602001807f61737365745f76616c75650000000000000000000000000000000000000000008152506020019350505050602060405180830381600087803b15801561014657600080fd5b505af115801561015a573d6000803e3d6000fd5b505050506040513d602081101561017057600080fd5b81019080805190602001909291905050505050565b611e3780620001956000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680639b80b0501461005c578063ea87152b14610129578063fcd7e3c1146101b0575b600080fd5b34801561006857600080fd5b50610113600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610234565b6040518082815260200191505060405180910390f35b34801561013557600080fd5b5061019a600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506112c8565b6040518082815260200191505060405180910390f35b3480156101bc57600080fd5b50610217600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506117d7565b604051808381526020018281526020019250505060405180910390f35b600080600080600080600080600080975060009650600095506000945061025a8c6117d7565b8097508198505050600087141515610395577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9750898b6040518082805190602001908083835b6020831015156102c657805182526020820191506020810190506020830392506102a1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b6020831015156103295780518252602082019150602081019050602083039250610304565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f8f6b9fa4d4bf04c7c1c3242d4a5c59ba22525b6761cf89e44becb27c606154bd8b6040518082815260200191505060405180910390a48798506112b9565b61039e8b6117d7565b80965081985050506000871415156104d9577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9750898b6040518082805190602001908083835b60208310151561040a57805182526020820191506020810190506020830392506103e5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b60208310151561046d5780518252602082019150602081019050602083039250610448565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f8f6b9fa4d4bf04c7c1c3242d4a5c59ba22525b6761cf89e44becb27c606154bd8b6040518082815260200191505060405180910390a48798506112b9565b8986101561060a577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9750898b6040518082805190602001908083835b60208310151561053b5780518252602082019150602081019050602083039250610516565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b60208310151561059e5780518252602082019150602081019050602083039250610579565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f8f6b9fa4d4bf04c7c1c3242d4a5c59ba22525b6761cf89e44becb27c606154bd8b6040518082815260200191505060405180910390a48798506112b9565b848a8601101561073d577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9750898b6040518082805190602001908083835b60208310151561066e5780518252602082019150602081019050602083039250610649565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b6020831015156106d157805182526020820191506020810190506020830392506106ac565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f8f6b9fa4d4bf04c7c1c3242d4a5c59ba22525b6761cf89e44becb27c606154bd8b6040518082815260200191505060405180910390a48798506112b9565b610745611d1c565b93508373ffffffffffffffffffffffffffffffffffffffff166313db93466040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156107ab57600080fd5b505af11580156107bf573d6000803e3d6000fd5b505050506040513d60208110156107d557600080fd5b810190808051906020019092919050505092508273ffffffffffffffffffffffffffffffffffffffff1663e942b5168d6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835260078152602001807f6163636f756e7400000000000000000000000000000000000000000000000000815250602001838103825284818151815260200191508051906020019080838360005b838110156108a857808201518184015260208101905061088d565b50505050905090810190601f1680156108d55780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156108f557600080fd5b505af1158015610909573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff16632ef8ba748b88036040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252600b8152602001807f61737365745f76616c756500000000000000000000000000000000000000000081525060200192505050600060405180830381600087803b1580156109b757600080fd5b505af11580156109cb573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663bf2b70a18d858773ffffffffffffffffffffffffffffffffffffffff16637857d7c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610a5157600080fd5b505af1158015610a65573d6000803e3d6000fd5b505050506040513d6020811015610a7b57600080fd5b81019080805190602001909291905050506040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825285818151815260200191508051906020019080838360005b83811015610b5b578082015181840152602081019050610b40565b50505050905090810190601f168015610b885780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015610ba957600080fd5b505af1158015610bbd573d6000803e3d6000fd5b505050506040513d6020811015610bd357600080fd5b81019080805190602001909291905050509150600182141515610d19577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9750898b6040518082805190602001908083835b602083101515610c4a5780518252602082019150602081019050602083039250610c25565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b602083101515610cad5780518252602082019150602081019050602083039250610c88565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f8f6b9fa4d4bf04c7c1c3242d4a5c59ba22525b6761cf89e44becb27c606154bd8b6040518082815260200191505060405180910390a48798506112b9565b8373ffffffffffffffffffffffffffffffffffffffff166313db93466040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610d7d57600080fd5b505af1158015610d91573d6000803e3d6000fd5b505050506040513d6020811015610da757600080fd5b810190808051906020019092919050505090508073ffffffffffffffffffffffffffffffffffffffff1663e942b5168c6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835260078152602001807f6163636f756e7400000000000000000000000000000000000000000000000000815250602001838103825284818151815260200191508051906020019080838360005b83811015610e7a57808201",
    "5181840152602081019050610e5f565b50505050905090810190601f168015610ea75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610ec757600080fd5b505af1158015610edb573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632ef8ba748b87016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252600b8152602001807f61737365745f76616c756500000000000000000000000000000000000000000081525060200192505050600060405180830381600087803b158015610f8957600080fd5b505af1158015610f9d573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663bf2b70a18c838773ffffffffffffffffffffffffffffffffffffffff16637857d7c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561102357600080fd5b505af1158015611037573d6000803e3d6000fd5b505050506040513d602081101561104d57600080fd5b81019080805190602001909291905050506040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825285818151815260200191508051906020019080838360005b8381101561112d578082015181840152602081019050611112565b50505050905090810190601f16801561115a5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561117b57600080fd5b505af115801561118f573d6000803e3d6000fd5b505050506040513d60208110156111a557600080fd5b810190808051906020019092919050505050898b6040518082805190602001908083835b6020831015156111ee57805182526020820191506020810190506020830392506111c9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b602083101515611251578051825260208201915060208101905060208303925061122c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f8f6b9fa4d4bf04c7c1c3242d4a5c59ba22525b6761cf89e44becb27c606154bd8b6040518082815260200191505060405180910390a48798505b50505050505050509392505050565b600080600080600080600080955060009450600093506112e7896117d7565b809550819650505060008514151561170957611301611d1c565b92508273ffffffffffffffffffffffffffffffffffffffff166313db93466040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561136757600080fd5b505af115801561137b573d6000803e3d6000fd5b505050506040513d602081101561139157600080fd5b810190808051906020019092919050505091508173ffffffffffffffffffffffffffffffffffffffff1663e942b5168a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835260078152602001807f6163636f756e7400000000000000000000000000000000000000000000000000815250602001838103825284818151815260200191508051906020019080838360005b83811015611464578082015181840152602081019050611449565b50505050905090810190601f1680156114915780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114b157600080fd5b505af11580156114c5573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff16632ef8ba74896040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252600b8152602001807f61737365745f76616c756500000000000000000000000000000000000000000081525060200192505050600060405180830381600087803b15801561157157600080fd5b505af1158015611585573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166331afac368a846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611644578082015181840152602081019050611629565b50505050905090810190601f1680156116715780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b15801561169157600080fd5b505af11580156116a5573d6000803e3d6000fd5b505050506040513d60208110156116bb57600080fd5b8101908080519060200190929190505050905060018114156116e05760009550611704565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe95505b61172d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95505b87896040518082805190602001908083835b602083101515611764578051825260208201915060208101905060208303925061173f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f91c95f04198617c60eaf2180fbca88fc192db379657df0e412a9f7dd4ebbe95d886040518082815260200191505060405180910390a385965050505050505092915050565b600080600080600080600061100194508473ffffffffffffffffffffffffffffffffffffffff1663f23f63c96040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260078152602001807f745f617373657400000000000000000000000000000000000000000000000000815250602001915050602060405180830381600087803b15801561188757600080fd5b505af115801561189b573d6000803e3d6000fd5b505050506040513d60208110156118b157600080fd5b810190808051906020019092919050505093508373ffffffffffffffffffffffffffffffffffffffff1663e8434e39898673ffffffffffffffffffffffffffffffffffffffff16637857d7c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561194557600080fd5b505af1158015611959573d6000803e3d6000fd5b505050506040513d602081101561196f57600080fd5b81019080805190602001909291905050506040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611a1d578082015181840152602081019050611a02565b50505050905090810190601f168015611a4a5780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b158015611a6a57600080fd5b505af1158015611a7e573d6000803e3d6000fd5b505050506040513d6020811015611a9457600080fd5b81019080805190602001909291905050509250600091508273ffffffffffffffffffffffffffffffffffffffff1663949d225d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611b0f57600080fd5b505af1158015611b23573d6000803e3d6000fd5b505050506040513d6020811015611b3957600080fd5b810190808051906020019092919050505060001415611b80577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8281915096509650611d12565b8273ffffffffffffffffffffffffffffffffffffffff1663846719e060006040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015611bf057600080fd5b505af1158015611c04573d6000803e3d6000fd5b505050506040513d6020811015611c1a57600080fd5b8101908080519060200190929190505050905060008173ffffffffffffffffffffffffffffffffffffffff1663fda69fae6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252600b8152602001807f61737365745f76616c7565000000000000000000000000000000000000000000815250602001915050602060405180830381600087803b158015611ccf57600080fd5b505af1158015611ce3573d6000803e3d6000fd5b505050506040513d6020811015611cf957600080fd5b8101908080519060200190929190505050819150965096505b5050505050915091565b600080600061100191508173ffffffffffffffffffffffffffffffffffffffff1663f23f63c96040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260078152602001807f745f617373657400000000000000000000000000000000000000000000000000815250602001915050602060405180830381600087803b158015611dc657600080fd5b505af1158015611dda573d6000803e3d6000fd5b505050506040513d6020811015611df057600080fd5b810190808051906020019092919050505090508092505050905600a165627a7a723058209583b88d65be16c71022714a76c8e98f0100607bcaab1f86faf7bc9433e6f36f0029"
  };

  public static final String BINARY = String.join("", BINARY_ARRAY);

  public static final String[] SM_BINARY_ARRAY = {
    "608060405234801561001057600080fd5b5061002861002d640100000000026401000000009004565b610185565b600061100190508073ffffffffffffffffffffffffffffffffffffffff1663c92a78016040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200180602001848103845260078152602001807f745f617373657400000000000000000000000000000000000000000000000000815250602001848103835260078152602001807f6163636f756e74000000000000000000000000000000000000000000000000008152506020018481038252600b8152602001807f61737365745f76616c75650000000000000000000000000000000000000000008152506020019350505050602060405180830381600087803b15801561014657600080fd5b505af115801561015a573d6000803e3d6000fd5b505050506040513d602081101561017057600080fd5b81019080805190602001909291905050505050565b611e3780620001956000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635b325d781461005c578063612d2bff146100e0578063b433c7ca146101ad575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610234565b604051808381526020018281526020019250505060405180910390f35b3480156100ec57600080fd5b50610197600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610779565b6040518082815260200191505060405180910390f35b3480156101b957600080fd5b5061021e600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192908035906020019092919050505061180d565b6040518082815260200191505060405180910390f35b600080600080600080600061100194508473ffffffffffffffffffffffffffffffffffffffff166359a48b656040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260078152602001807f745f617373657400000000000000000000000000000000000000000000000000815250602001915050602060405180830381600087803b1580156102e457600080fd5b505af11580156102f8573d6000803e3d6000fd5b505050506040513d602081101561030e57600080fd5b810190808051906020019092919050505093508373ffffffffffffffffffffffffffffffffffffffff1663d8ac5957898673ffffffffffffffffffffffffffffffffffffffff1663c74f8caf6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156103a257600080fd5b505af11580156103b6573d6000803e3d6000fd5b505050506040513d60208110156103cc57600080fd5b81019080805190602001909291905050506040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561047a57808201518184015260208101905061045f565b50505050905090810190601f1680156104a75780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b1580156104c757600080fd5b505af11580156104db573d6000803e3d6000fd5b505050506040513d60208110156104f157600080fd5b81019080805190602001909291905050509250600091508273ffffffffffffffffffffffffffffffffffffffff1663d3e9af5a6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b505050506040513d602081101561059657600080fd5b8101908080519060200190929190505050600014156105dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828191509650965061076f565b8273ffffffffffffffffffffffffffffffffffffffff16633dd2b61460006040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561064d57600080fd5b505af1158015610661573d6000803e3d6000fd5b505050506040513d602081101561067757600080fd5b8101908080519060200190929190505050905060008173ffffffffffffffffffffffffffffffffffffffff16634900862e6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018281038252600b8152602001807f61737365745f76616c7565000000000000000000000000000000000000000000815250602001915050602060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b505050506040513d602081101561075657600080fd5b8101908080519060200190929190505050819150965096505b5050505050915091565b600080600080600080600080600080975060009650600095506000945061079f8c610234565b80975081985050506000871415156108da577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9750898b6040518082805190602001908083835b60208310151561080b57805182526020820191506020810190506020830392506107e6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b60208310151561086e5780518252602082019150602081019050602083039250610849565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f105af2c562df33af7eaa9de5fb0c18d8d30f281a18f95a8f76b44353a322693c8b6040518082815260200191505060405180910390a48798506117fe565b6108e38b610234565b8096508198505050600087141515610a1e577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9750898b6040518082805190602001908083835b60208310151561094f578051825260208201915060208101905060208303925061092a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b6020831015156109b2578051825260208201915060208101905060208303925061098d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f105af2c562df33af7eaa9de5fb0c18d8d30f281a18f95a8f76b44353a322693c8b6040518082815260200191505060405180910390a48798506117fe565b89861015610b4f577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9750898b6040518082805190602001908083835b602083101515610a805780518252602082019150602081019050602083039250610a5b565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b602083101515610ae35780518252602082019150602081019050602083039250610abe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f105af2c562df33af7eaa9de5fb0c18d8d30f281a18f95a8f76b44353a322693c8b6040518082815260200191505060405180910390a48798506117fe565b848a86011015610c82577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9750898b6040518082805190602001908083835b602083101515610bb35780518252602082019150602081019050602083039250610b8e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b602083101515610c165780518252602082019150602081019050602083039250610bf1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f105af2c562df33af7eaa9de5fb0c18d8d30f281a18f95a8f76b44353a322693c8b6040518082815260200191505060405180910390a48798506117fe565b610c8a611d1c565b93508373ffffffffffffffffffffffffffffffffffffffff16635887ab246040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610cf057600080fd5b505af1158015610d04573d6000803e3d6000fd5b505050506040513d6020811015610d1a57600080fd5b810190808051906020019092919050505092508273ffffffffffffffffffffffffffffffffffffffff16631a391cb48d6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835260078152602001807f6163636f756e7400000000000000000000000000000000000000000000000000815250602001838103825284818151815260200191508051906020019080838360005b83811015610ded578082015181840152602081019050610dd2565b50505050905090810190601f168015610e1a5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610e3a57600080fd5b505af1158015610e4e573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff1663",
    "def426988b88036040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252600b8152602001807f61737365745f76616c756500000000000000000000000000000000000000000081525060200192505050600060405180830381600087803b158015610efc57600080fd5b505af1158015610f10573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663664b37d68d858773ffffffffffffffffffffffffffffffffffffffff1663c74f8caf6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610f9657600080fd5b505af1158015610faa573d6000803e3d6000fd5b505050506040513d6020811015610fc057600080fd5b81019080805190602001909291905050506040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825285818151815260200191508051906020019080838360005b838110156110a0578082015181840152602081019050611085565b50505050905090810190601f1680156110cd5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156110ee57600080fd5b505af1158015611102573d6000803e3d6000fd5b505050506040513d602081101561111857600080fd5b8101908080519060200190929190505050915060018214151561125e577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9750898b6040518082805190602001908083835b60208310151561118f578051825260208201915060208101905060208303925061116a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b6020831015156111f257805182526020820191506020810190506020830392506111cd565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f105af2c562df33af7eaa9de5fb0c18d8d30f281a18f95a8f76b44353a322693c8b6040518082815260200191505060405180910390a48798506117fe565b8373ffffffffffffffffffffffffffffffffffffffff16635887ab246040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156112c257600080fd5b505af11580156112d6573d6000803e3d6000fd5b505050506040513d60208110156112ec57600080fd5b810190808051906020019092919050505090508073ffffffffffffffffffffffffffffffffffffffff16631a391cb48c6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835260078152602001807f6163636f756e7400000000000000000000000000000000000000000000000000815250602001838103825284818151815260200191508051906020019080838360005b838110156113bf5780820151818401526020810190506113a4565b50505050905090810190601f1680156113ec5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561140c57600080fd5b505af1158015611420573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff1663def426988b87016040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252600b8152602001807f61737365745f76616c756500000000000000000000000000000000000000000081525060200192505050600060405180830381600087803b1580156114ce57600080fd5b505af11580156114e2573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663664b37d68c838773ffffffffffffffffffffffffffffffffffffffff1663c74f8caf6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561156857600080fd5b505af115801561157c573d6000803e3d6000fd5b505050506040513d602081101561159257600080fd5b81019080805190602001909291905050506040518463ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825285818151815260200191508051906020019080838360005b83811015611672578082015181840152602081019050611657565b50505050905090810190601f16801561169f5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156116c057600080fd5b505af11580156116d4573d6000803e3d6000fd5b505050506040513d60208110156116ea57600080fd5b810190808051906020019092919050505050898b6040518082805190602001908083835b602083101515611733578051825260208201915060208101905060208303925061170e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390208d6040518082805190602001908083835b6020831015156117965780518252602082019150602081019050602083039250611771565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f105af2c562df33af7eaa9de5fb0c18d8d30f281a18f95a8f76b44353a322693c8b6040518082815260200191505060405180910390a48798505b50505050505050509392505050565b6000806000806000806000809550600094506000935061182c89610234565b8095508196505050600085141515611c4e57611846611d1c565b92508273ffffffffffffffffffffffffffffffffffffffff16635887ab246040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156118ac57600080fd5b505af11580156118c0573d6000803e3d6000fd5b505050506040513d60208110156118d657600080fd5b810190808051906020019092919050505091508173ffffffffffffffffffffffffffffffffffffffff16631a391cb48a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808060200180602001838103835260078152602001807f6163636f756e7400000000000000000000000000000000000000000000000000815250602001838103825284818151815260200191508051906020019080838360005b838110156119a957808201518184015260208101905061198e565b50505050905090810190601f1680156119d65780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156119f657600080fd5b505af1158015611a0a573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663def42698896040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018381526020018281038252600b8152602001807f61737365745f76616c756500000000000000000000000000000000000000000081525060200192505050600060405180830381600087803b158015611ab657600080fd5b505af1158015611aca573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff16634c6f30c08a846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611b89578082015181840152602081019050611b6e565b50505050905090810190601f168015611bb65780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b158015611bd657600080fd5b505af1158015611bea573d6000803e3d6000fd5b505050506040513d6020811015611c0057600080fd5b810190808051906020019092919050505090506001811415611c255760009550611c49565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe95505b611c72565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95505b87896040518082805190602001908083835b602083101515611ca95780518252602082019150602081019050602083039250611c84565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f7ac7a04970319ae8fc5b92fe177d000fee3c00c92f8e78aae13d6571f17c351f886040518082815260200191505060405180910390a385965050505050505092915050565b600080600061100191508173ffffffffffffffffffffffffffffffffffffffff166359a48b656040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825260078152602001807f745f617373657400000000000000000000000000000000000000000000000000815250602001915050602060405180830381600087803b158015611dc657600080fd5b505af1158015611dda573d6000803e3d6000fd5b505050506040513d6020811015611df057600080fd5b810190808051906020019092919050505090508092505050905600a165627a7a72305820359a39cb7ac28563ad7fa716aa44afd6af26313abd44cb973be11893df24b1e30029"
  };

  public static final String SM_BINARY = String.join("", SM_BINARY_ARRAY);

  public static final String[] ABI_ARRAY = {
    "[{\"constant\":false,\"inputs\":[{\"name\":\"from_account\",\"type\":\"string\"},{\"name\":\"to_account\",\"type\":\"string\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"account\",\"type\":\"string\"},{\"name\":\"asset_value\",\"type\":\"uint256\"}],\"name\":\"register\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"string\"}],\"name\":\"select\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"},{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ret\",\"type\":\"int256\"},{\"indexed\":true,\"name\":\"account\",\"type\":\"string\"},{\"indexed\":true,\"name\":\"asset_value\",\"type\":\"uint256\"}],\"name\":\"RegisterEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ret\",\"type\":\"int256\"},{\"indexed\":true,\"name\":\"from_account\",\"type\":\"string\"},{\"indexed\":true,\"name\":\"to_account\",\"type\":\"string\"},{\"indexed\":true,\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferEvent\",\"type\":\"event\"}]"
  };

  public static final String ABI = String.join("", ABI_ARRAY);

  public static final String FUNC_TRANSFER = "transfer";

  public static final String FUNC_REGISTER = "register";

  public static final String FUNC_SELECT = "select";

  public static final Event REGISTEREVENT_EVENT =
      new Event(
          "RegisterEvent",
          Arrays.<TypeReference<?>>asList(
              new TypeReference<Int256>() {},
              new TypeReference<Utf8String>(true) {},
              new TypeReference<Uint256>(true) {}));;

  public static final Event TRANSFEREVENT_EVENT =
      new Event(
          "TransferEvent",
          Arrays.<TypeReference<?>>asList(
              new TypeReference<Int256>() {},
              new TypeReference<Utf8String>(true) {},
              new TypeReference<Utf8String>(true) {},
              new TypeReference<Uint256>(true) {}));;

  protected Asset(String contractAddress, Client client, CryptoKeyPair credential) {
    super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
  }

  public static String getBinary(CryptoSuite cryptoSuite) {
    return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
  }

  public TransactionReceipt transfer(String from_account, String to_account, BigInteger amount) {
    final Function function =
        new Function(
            FUNC_TRANSFER,
            Arrays.<Type>asList(
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from_account),
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to_account),
                new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)),
            Collections.<TypeReference<?>>emptyList());
    return executeTransaction(function);
  }

  public void transfer(
      String from_account, String to_account, BigInteger amount, TransactionCallback callback) {
    final Function function =
        new Function(
            FUNC_TRANSFER,
            Arrays.<Type>asList(
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from_account),
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to_account),
                new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)),
            Collections.<TypeReference<?>>emptyList());
    asyncExecuteTransaction(function, callback);
  }

  public String getSignedTransactionForTransfer(
      String from_account, String to_account, BigInteger amount) {
    final Function function =
        new Function(
            FUNC_TRANSFER,
            Arrays.<Type>asList(
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from_account),
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to_account),
                new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)),
            Collections.<TypeReference<?>>emptyList());
    return createSignedTransaction(function);
  }

  public Tuple3<String, String, BigInteger> getTransferInput(
      TransactionReceipt transactionReceipt) {
    String data = transactionReceipt.getInput().substring(10);
    final Function function =
        new Function(
            FUNC_TRANSFER,
            Arrays.<Type>asList(),
            Arrays.<TypeReference<?>>asList(
                new TypeReference<Utf8String>() {},
                new TypeReference<Utf8String>() {},
                new TypeReference<Uint256>() {}));
    List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
    return new Tuple3<String, String, BigInteger>(
        (String) results.get(0).getValue(),
        (String) results.get(1).getValue(),
        (BigInteger) results.get(2).getValue());
  }

  public Tuple1<BigInteger> getTransferOutput(TransactionReceipt transactionReceipt) {
    String data = transactionReceipt.getOutput();
    final Function function =
        new Function(
            FUNC_TRANSFER,
            Arrays.<Type>asList(),
            Arrays.<TypeReference<?>>asList(new TypeReference<Int256>() {}));
    List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
    return new Tuple1<BigInteger>((BigInteger) results.get(0).getValue());
  }

  public TransactionReceipt register(String account, BigInteger asset_value) {
    final Function function =
        new Function(
            FUNC_REGISTER,
            Arrays.<Type>asList(
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(account),
                new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(asset_value)),
            Collections.<TypeReference<?>>emptyList());
    return executeTransaction(function);
  }

  public void register(String account, BigInteger asset_value, TransactionCallback callback) {
    final Function function =
        new Function(
            FUNC_REGISTER,
            Arrays.<Type>asList(
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(account),
                new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(asset_value)),
            Collections.<TypeReference<?>>emptyList());
    asyncExecuteTransaction(function, callback);
  }

  public String getSignedTransactionForRegister(String account, BigInteger asset_value) {
    final Function function =
        new Function(
            FUNC_REGISTER,
            Arrays.<Type>asList(
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(account),
                new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(asset_value)),
            Collections.<TypeReference<?>>emptyList());
    return createSignedTransaction(function);
  }

  public Tuple2<String, BigInteger> getRegisterInput(TransactionReceipt transactionReceipt) {
    String data = transactionReceipt.getInput().substring(10);
    final Function function =
        new Function(
            FUNC_REGISTER,
            Arrays.<Type>asList(),
            Arrays.<TypeReference<?>>asList(
                new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}));
    List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
    return new Tuple2<String, BigInteger>(
        (String) results.get(0).getValue(), (BigInteger) results.get(1).getValue());
  }

  public Tuple1<BigInteger> getRegisterOutput(TransactionReceipt transactionReceipt) {
    String data = transactionReceipt.getOutput();
    final Function function =
        new Function(
            FUNC_REGISTER,
            Arrays.<Type>asList(),
            Arrays.<TypeReference<?>>asList(new TypeReference<Int256>() {}));
    List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
    return new Tuple1<BigInteger>((BigInteger) results.get(0).getValue());
  }

  public Tuple2<BigInteger, BigInteger> select(String account) throws ContractException {
    final Function function =
        new Function(
            FUNC_SELECT,
            Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(account)),
            Arrays.<TypeReference<?>>asList(
                new TypeReference<Int256>() {}, new TypeReference<Uint256>() {}));
    List<Type> results = executeCallWithMultipleValueReturn(function);
    return new Tuple2<BigInteger, BigInteger>(
        (BigInteger) results.get(0).getValue(), (BigInteger) results.get(1).getValue());
  }

  public List<RegisterEventEventResponse> getRegisterEventEvents(
      TransactionReceipt transactionReceipt) {
    List<Contract.EventValuesWithLog> valueList =
        extractEventParametersWithLog(REGISTEREVENT_EVENT, transactionReceipt);
    ArrayList<RegisterEventEventResponse> responses =
        new ArrayList<RegisterEventEventResponse>(valueList.size());
    for (Contract.EventValuesWithLog eventValues : valueList) {
      RegisterEventEventResponse typedResponse = new RegisterEventEventResponse();
      typedResponse.log = eventValues.getLog();
      typedResponse.account = (byte[]) eventValues.getIndexedValues().get(0).getValue();
      typedResponse.asset_value = (BigInteger) eventValues.getIndexedValues().get(1).getValue();
      typedResponse.ret = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
      responses.add(typedResponse);
    }
    return responses;
  }

  public void subscribeRegisterEventEvent(
      String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
    String topic0 = eventEncoder.encode(REGISTEREVENT_EVENT);
    subscribeEvent(ABI, BINARY, topic0, fromBlock, toBlock, otherTopics, callback);
  }

  public void subscribeRegisterEventEvent(EventCallback callback) {
    String topic0 = eventEncoder.encode(REGISTEREVENT_EVENT);
    subscribeEvent(ABI, BINARY, topic0, callback);
  }

  public List<TransferEventEventResponse> getTransferEventEvents(
      TransactionReceipt transactionReceipt) {
    List<Contract.EventValuesWithLog> valueList =
        extractEventParametersWithLog(TRANSFEREVENT_EVENT, transactionReceipt);
    ArrayList<TransferEventEventResponse> responses =
        new ArrayList<TransferEventEventResponse>(valueList.size());
    for (Contract.EventValuesWithLog eventValues : valueList) {
      TransferEventEventResponse typedResponse = new TransferEventEventResponse();
      typedResponse.log = eventValues.getLog();
      typedResponse.from_account = (byte[]) eventValues.getIndexedValues().get(0).getValue();
      typedResponse.to_account = (byte[]) eventValues.getIndexedValues().get(1).getValue();
      typedResponse.amount = (BigInteger) eventValues.getIndexedValues().get(2).getValue();
      typedResponse.ret = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
      responses.add(typedResponse);
    }
    return responses;
  }

  public void subscribeTransferEventEvent(
      String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
    String topic0 = eventEncoder.encode(TRANSFEREVENT_EVENT);
    subscribeEvent(ABI, BINARY, topic0, fromBlock, toBlock, otherTopics, callback);
  }

  public void subscribeTransferEventEvent(EventCallback callback) {
    String topic0 = eventEncoder.encode(TRANSFEREVENT_EVENT);
    subscribeEvent(ABI, BINARY, topic0, callback);
  }

  public static Asset load(String contractAddress, Client client, CryptoKeyPair credential) {
    return new Asset(contractAddress, client, credential);
  }

  public static Asset deploy(Client client, CryptoKeyPair credential) throws ContractException {
    return deploy(Asset.class, client, credential, getBinary(client.getCryptoSuite()), "");
  }

  public static class RegisterEventEventResponse {
    public TransactionReceipt.Logs log;

    public byte[] account;

    public BigInteger asset_value;

    public BigInteger ret;
  }

  public static class TransferEventEventResponse {
    public TransactionReceipt.Logs log;

    public byte[] from_account;

    public byte[] to_account;

    public BigInteger amount;

    public BigInteger ret;
  }
}
